// Decompiled by DJ v3.9.9.91 Copyright 2005 Atanas Neshkov  Date: 4/12/2007 10:47:14
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3) 
// Source File Name:   Matrix3D.java

package mathematics;


// Referenced classes of package de.escape.quincunx.trafo:
//            Point2D, Vector2D

public final class Matrix3D
{

    public Matrix3D()
    {
        xx = yy = ww = 1.0F;
    }

    public Matrix3D(Matrix3D m)
    {
        xx = m.xx;
        xy = m.xy;
        xw = m.xw;
        yx = m.yx;
        yy = m.yy;
        yw = m.yw;
        wx = m.wx;
        wy = m.wy;
        ww = m.ww;
    }

    public Matrix3D(float mxx, float mxy, float mxw, float myx, float myy, float myw, float mwx, 
            float mwy, float mww)
    {
        xx = mxx;
        xy = mxy;
        xw = mxw;
        yx = myx;
        yy = myy;
        yw = myw;
        wx = mwx;
        wy = mwy;
        ww = mww;
    }

    public void identity()
    {
        xx = yy = ww = 1.0F;
        xy = xw = yx = yw = wx = wy = 0.0F;
    }

    public void transponize()
    {
        float t = xy;
        xy = yx;
        yx = t;
        t = xw;
        xw = wx;
        wx = t;
        t = yw;
        yw = wy;
        wy = t;
    }

    public Vector2D mult(Vector2D v)
    {
        return new Vector2D(xx * v.x + xy * v.y, yx * v.x + yy * v.y);
    }

    public void transform(Vector2D v)
    {
        float x = xx * v.x + xy * v.y;
        float y = yx * v.x + yy * v.y;
        v.x = x;
        v.y = y;
    }

    public Point2D mult(Point2D p)
    {
        Point2D ret = new Point2D(xx * p.x + xy * p.y + xw, yx * p.x + yy * p.y + yw);
        ret.scale(1.0F / (wx * p.x + wy * p.y + ww));
        return ret;
    }

    public void transform(Point2D p)
    {
        float x = xx * p.x + xy * p.y + xw;
        float y = yx * p.x + yy * p.y + yw;
        float w = wx * p.x + wy * p.y + ww;
        p.x = x / w;
        p.y = y / w;
    }

    public Matrix3D mult(Matrix3D m)
    {
        if(m != null)
            return new Matrix3D(xx * m.xx + xy * m.yx + xw * m.wx, xx * m.xy + xy * m.yy + xw * m.wy, xx * m.xw + xy * m.yw + xw * m.ww, yx * m.xx + yy * m.yx + yw * m.wx, yx * m.xy + yy * m.yy + yw * m.wy, yx * m.xw + yy * m.yw + yw * m.ww, wx * m.xx + wy * m.yx + ww * m.wx, wx * m.xy + wy * m.yy + ww * m.wy, wx * m.xw + wy * m.yw + ww * m.ww);
        else
            return new Matrix3D(this);
    }

    public void multBy(Matrix3D m)
    {
        float x = xx * m.xx + xy * m.yx + xw * m.wx;
        float y = xx * m.xy + xy * m.yy + xw * m.wy;
        float w = xx * m.xw + xy * m.yw + xw * m.ww;
        xx = x;
        xy = y;
        xw = w;
        x = yx * m.xx + yy * m.yx + yw * m.wx;
        y = yx * m.xy + yy * m.yy + yw * m.wy;
        w = yx * m.xw + yy * m.yw + yw * m.ww;
        yx = x;
        yy = y;
        yw = w;
        x = wx * m.xx + wy * m.yx + ww * m.wx;
        y = wx * m.xy + wy * m.yy + ww * m.wy;
        w = wx * m.xw + wy * m.yw + ww * m.ww;
        wx = x;
        wy = y;
        ww = w;
    }

    public void multLeftBy(Matrix3D m)
    {
        float x = m.xx * xx + m.xy * yx + m.xw * wx;
        float y = m.yx * xx + m.yy * yx + m.yw * wx;
        float w = m.wx * xx + m.wy * yx + m.ww * wx;
        xx = x;
        yx = y;
        wx = w;
        x = m.xx * xy + m.xy * yy + m.xw * wy;
        y = m.yx * xy + m.yy * yy + m.yw * wy;
        w = m.wx * xy + m.wy * yy + m.ww * wy;
        xy = x;
        yy = y;
        wy = w;
        x = m.xx * xw + m.xy * yw + m.xw * ww;
        y = m.yx * xw + m.yy * yw + m.yw * ww;
        w = m.wx * xw + m.wy * yw + m.ww * ww;
        xw = x;
        yw = y;
        ww = w;
    }

    public void translate(float x, float y)
    {
        xw += x * xx + y * xy;
        yw += x * yx + y * yy;
        ww += x * wx + y * wy;
    }

    public void translate(Vector2D v)
    {
        translate(v.x, v.y);
    }

    public void translateLeft(float x, float y)
    {
        if(x != 0.0F)
        {
            xx += x * wx;
            xy += x * wy;
            xw += x * ww;
        }
        if(y != 0.0F)
        {
            yx += y * wx;
            yy += y * wy;
            yw += y * ww;
        }
    }

    public void translateLeft(Vector2D v)
    {
        translateLeft(v.x, v.y);
    }

    public void moveBy(float x, float y)
    {
        if(x != 0.0F)
        {
            xx += x * xw;
            yx += x * yw;
            wx += x * ww;
        }
        if(y != 0.0F)
        {
            xy += y * xw;
            yy += y * yw;
            wy += y * ww;
        }
    }

    public void moveBy(Vector2D v)
    {
        moveBy(v.x, v.y);
    }

    public void rot(double theta)
    {
        if(theta == 0.0D)
        {
            return;
        } else
        {
            double ct = Math.cos(theta);
            double st = Math.sin(theta);
            float Nx = (float)((double)xx * ct - (double)yx * st);
            float Ny = (float)((double)xx * st + (double)yx * ct);
            xx = Nx;
            yx = Ny;
            Nx = (float)((double)xy * ct - (double)yy * st);
            Ny = (float)((double)xy * st + (double)yy * ct);
            xy = Nx;
            yy = Ny;
            Nx = (float)((double)xw * ct - (double)yw * st);
            Ny = (float)((double)xw * st + (double)yw * ct);
            xw = Nx;
            yw = Ny;
            return;
        }
    }

    public void scale(float f)
    {
        xx *= f;
        yx *= f;
        wx *= f;
        xy *= f;
        yy *= f;
        wy *= f;
    }

    public void scale(float fx, float fy)
    {
        xx *= fx;
        yx *= fx;
        wx *= fx;
        xy *= fy;
        yy *= fy;
        wy *= fy;
    }

    public void transform(Point2D v[], int tx[], int ty[], int npoints)
    {
        for(int i = npoints; --i >= 0;)
        {
            Point2D tmp = mult(v[i]);
            tx[i] = (int)tmp.x;
            ty[i] = (int)tmp.y;
        }

    }

    public String toString()
    {
        return new String((new StringBuffer()).append("{{").append(xx).append(",").append(xy).append(",").append(xw).append("},{").append(yx).append(",").append(yy).append(",").append(yw).append("},{").append(wx).append(",").append(wy).append(",").append(ww).append("}}"));
    }

    private static final double DEG2RAD = 0.017453292519943295D;
    public float xx;
    public float xy;
    public float xw;
    public float yx;
    public float yy;
    public float yw;
    public float wx;
    public float wy;
    public float ww;
}